package com.ddch.testsocket;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.connect)
    Button connect;
    @BindView(R.id.disconnect)
    Button disconnect;
    @BindView(R.id.receive_message)
    TextView receive_message;
    @BindView(R.id.Receive)
    Button Receive;
    @BindView(R.id.edit)
    EditText edit;
    @BindView(R.id.send)
    Button send;
    private Unbinder unbinder;
    // 线程池  为了方便展示，此处直接采用线程池进行线程管理，而没有一个个开线程
    private ExecutorService mTheadPool;
    /*z主线程Handler 用于将从服务器获取的消息显示出来*/
    private Handler mMainHandler;
    // 接收服务器发送过来的消息
    private String response;
    // Socket变量
    private Socket socket;
    // 输入流对象
    private InputStream is;
    // 输入流读取器对象
    private InputStreamReader isr;
    private BufferedReader br;
    // 输出流对象
    private OutputStream outputStream;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        unbinder = ButterKnife.bind(this);
        // 初始化线程池
        mTheadPool = Executors.newCachedThreadPool();
        // 实例化主线程，用于更新接收过来的消息
        mMainHandler = new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                if(msg.what == 0){
                    receive_message.setText(response);
                }
            }
        };
    }
    @OnClick({R.id.connect, R.id.disconnect,R.id.Receive, R.id.send })
    public void  onClickListenerEvent(View view){
        switch (view.getId()){
            case R.id.connect:
                // 创建客户端 & 服务器连接
                // 利用线程池直接开启一个线程 & 执行该线程
                mTheadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 创建Socket对象 & 指定服务端的IP及端口号
                            socket = new Socket("192.168.128.76", 8989);
                            // 判断客户端与服务器是否连接成功
                            Log.d("lm", String.valueOf(socket.isConnected()));
                            mMainHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this, String.valueOf(socket.isConnected()), Toast.LENGTH_LONG).show();
                                }
                            });
                        } catch (IOException e) {
                            e.printStackTrace();
                            Looper.prepare();
                            Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                            Looper.loop();
                        }
                    }
                });
                break;
            case R.id.disconnect:
                // 断开客户端 & 服务器连接
                try {
                    if(outputStream == null || br == null || socket == null)
                        return;
                    // 断开客户端发送到服务器的连接，即关闭输出流对象OutputStream
                    outputStream.close();
                    // 断开服务器发送到客户端的连接，即关闭输入流读取器对象BufferedReader
                    br.close();
                    // 最终关闭整个Socket连接
                    socket.close();
                    // 判断客户端和服务器是否已经断开连接
                    Log.d("liaoming", String.valueOf(socket.isClosed()));
                    mMainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, String.valueOf(socket.isConnected()), Toast.LENGTH_LONG).show();
                        }
                    });

                } catch (IOException e) {
                    e.printStackTrace();
                }

                break;
            case R.id.Receive:
                // 接收服务器消息
                // 利用线程池直接开启一个线程 & 执行该线程
                mTheadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            if(socket == null)
                                return;
                            while(true) {
                                // 步骤1：创建输入流对象InputStream
                                is = socket.getInputStream();
                                // 步骤2：创建输入流读取器对象，并传入输入流对象
                                // 该对象作用：获取服务器返回的数据
                                isr = new InputStreamReader(is);
                                br = new BufferedReader(isr);
                                // 步骤3：通过输入流读取器对象，接收服务器发送过来的数据
                                response = br.readLine();
                                // 步骤4：通知主线程，将接收的消息显示到界面
                                Message msg = Message.obtain();
                                msg.what = 0;
                                mMainHandler.sendMessage(msg);
                            }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                });
                break;
            case R.id.send:
                /*发送消息给服务器*/
                mTheadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        // 利用线程池直接开启一个线程 & 执行该线程
                        try {
                            // 步骤1：从Socket获得输出流对象OutputStream
                            // 该对象作用：发送数据
                            if(socket == null)
                                return;
                            outputStream = socket.getOutputStream();
                            // 步骤2：写入需要发送的数据到输出流中
                            outputStream.write((edit.getText().toString()+"\n").getBytes("utf-8"));
                            // 特别注意：数据的结尾加上换行符才可让服务器端的readLine()停止阻塞
                            // 步骤3：发送数据到服务端
                            outputStream.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                });
                break;
            default:
                break;
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
    }
}
